/*
 * @Author: 颜礼田 2564217790@qq.com
 * @Date: 2024-08-15 01:06:42
 * @LastEditors: 颜礼田 2564217790@qq.com
 * @LastEditTime: 2024-09-07 16:56:25
 * @FilePath: /server/script/server.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
const fs = require('fs');
const { exec } = require('child_process');

const args = process.argv;
const folderName = args[2];

function titleCase(name) {
  const [first, ...end] = name.split('');
  return `${first.toUpperCase()}${end
    .map(d => d.toLowerCase())
    .join('')}`.replace(/_\D/g, match => {
    return match.charAt(1).toUpperCase();
  });
}

function runYarnCommand(command, callback) {
  exec(`yarn ${command}`, (error, stdout, stderr) => {
    if (error) {
      console.error(`执行出错: ${error}`);
      return;
    }
    if (stderr) {
      console.error(`命令错误输出: ${stderr}`);
    }
    console.log(`命令输出: ${stdout}`);
    callback && callback();
  });
}

function create_entity(schema, key) {
  const cols = schema.map(ele => {
    const field = !ele.nullable
      ? `${ele.key}: ${ele.ts_type};`
      : `${ele.key}?: ${ele.ts_type};`;
    return `
    @Column({
      type: '${ele.db_type}',
      length: ${ele.length},
      nullable: ${ele.nullable},
      default: ${ele.value},
      comment: '${ele.comment}',
    })
    ${field}
    `;
  });
  const s = schema.map(ele => {
    const field = !ele.nullable
      ? `${ele.key}: ${ele.ts_type};`
      : `${ele.key}?: ${ele.ts_type};`;
    return `
    // ${ele.comment}
    ${field}
    `;
  });
  const tpl = `
import { Column, Entity } from 'typeorm';
import { DBColumns } from '../';
import { ${titleCase(key)}Schema } from '../../schema';

@Entity('${key}')

export class ${titleCase(key)} extends DBColumns implements ${titleCase(
    key
  )}Schema {
  ${cols.join('\n')}
}
`;

  const inter = `
import { BaseColumns } from '../base';
export interface ${titleCase(key)}Schema extends BaseColumns {
${s.join('\n')}
}
`;
  fs.mkdir(`./src/model/${key}`, err => {
    if (err) {
      if (err.errno !== -17 && err.errno !== -4075) {
        console.error(err);
        return;
      }
    }
    fs.writeFileSync(`./src/model/${key}/${key}.ts`, tpl, {
      encoding: 'utf-8',
    });
  });

  fs.mkdir(`./src/schema/${key}`, err => {
    if (err) {
      if (err.errno !== -17 && err.errno !== -4075) {
        console.error(err);
        return;
      }
    }

    fs.writeFileSync(`./src/schema/${key}/index.ts`, inter, {
      encoding: 'utf-8',
    });
  });

  fs.appendFileSync('./src/schema/index.ts', `\n\texport * from './${key}'`, {
    encoding: 'utf-8',
  });
}

function create_service(key) {
  const tpl = `
import { Provide } from '@midwayjs/core';
import { ServicesImpl } from '../impl';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { ${titleCase(key)} } from '../../model/${key}/${key}';

@Provide()
export class ${titleCase(key)}Service extends ServicesImpl {
  /**
   * 覆盖实体
   */
  @InjectEntityModel(${titleCase(key)})
  services: Repository<${titleCase(key)}>;

  /**
   * 重写关系
   */
  relations: Array<string>;

  constructor() {
    super();
    this.relations = [];
  }
}
`;

  fs.mkdir(`./src/service/${key}`, err => {
    if (err) {
      if (err.errno !== -17 && err.errno !== -4075) {
        return;
      }
    }
    fs.writeFileSync(`./src/service/${key}/${key}.service.ts`, tpl, {
      encoding: 'utf-8',
    });
  });
}

function create_controller(key) {
  const tpl = `
import {
  Body,
  Controller,
  Del,
  Get,
  Inject,
  Post,
  Put,
  Query,
} from '@midwayjs/core';
import { ${titleCase(key)}Service } from '../../service/${key}/${key}.service';
import { Validate } from '@midwayjs/validate';
import { ListParamsValidator, StrIdValidator } from '../../validator';
import { Edit${titleCase(key)}Validator, Save${titleCase(
    key
  )}Validator } from '../../validator/${key}/${key}';

@Controller('/${key}', { tagName: '' })
export class ${titleCase(key)}Controller {
  @Inject()
  ${key}Service: ${titleCase(key)}Service;

  @Post('/list', { summary: '列表' })
  @Validate()
  async list(@Body() body: ListParamsValidator) {
    const data = await this.${key}Service.list(body);
    return Object.assign(data, body);
  }

  @Post('/save', { summary: '保存' })
  @Validate()
  async save(@Body() body: Save${titleCase(key)}Validator) {
    return await this.${key}Service.save(body);
  }

  @Get('/info', { summary: '信息' })
  @Validate()
  async info(@Query() body: StrIdValidator) {
    return await this.${key}Service.info(body.id);
  }

  @Del('/remove', { summary: '删除' })
  @Validate()
  async remove(@Query() body: StrIdValidator) {
    return await this.${key}Service.remove(body.id);
  }

  @Del('/delete', { summary: '（真）删除' })
  @Validate()
  async realRemove(@Query() body: StrIdValidator) {
    return await this.${key}Service.realRemove(body.id);
  }

  @Put('/edit', { summary: '编辑' })
  @Validate()
  async edit(@Query() query: StrIdValidator, @Body() body: Edit${titleCase(
    key
  )}Validator) {
    const ${key} = await this.${key}Service.info(query.id);
    Object.assign(${key}, body);
    return await this.${key}Service.save(${key});
  }
}
  `;

  fs.mkdir(`./src/controller/${key}`, err => {
    if (err) {
      if (err.errno !== -17 && err.errno !== -4075) {
        return;
      }
    }
    fs.writeFileSync(`./src/controller/${key}/${key}.ts`, tpl, {
      encoding: 'utf-8',
    });
  });
}

function create_validator(schema, key) {
  const cols = schema.map(ele => {
    const rule = !ele.nullable
      ? `@Rule(RuleType.${ele.ts_type}().required())`
      : '@Rule(RuleType.alternatives(alternatives))';

    const field = !ele.nullable
      ? `${ele.key}: ${ele.ts_type};`
      : `${ele.key}?: ${ele.ts_type};`;
    return `
    @ApiProperty({
      type: '${ele.ts_type}',
      title: '${ele.comment}',
      example: '${ele.value}',
      description: '${ele.comment}',
      required: ${!ele.nullable},
    })
    ${rule}
    ${field}
    `;
  });

  const nullable = schema.map(ele => {
    return `
    @ApiProperty({
      type: '${ele.ts_type}',
        title: '${ele.comment}',
        example: '${ele.value}',
        description: '${ele.comment}',
        required: false,
    })
    @Rule(RuleType.alternatives(alternatives))
    ${ele.key}?: ${ele.ts_type};
  `;
  });
  const tpl = `
import { ApiProperty } from '@midwayjs/swagger';
import { Rule, RuleType } from '@midwayjs/validate';
import { alternatives } from '..';
import { ${titleCase(key)}Schema } from '../../schema';

export class Save${titleCase(key)}Validator implements ${titleCase(key)}Schema {
  ${cols.join('\n')}
}

export class Edit${titleCase(key)}Validator implements Partial<${titleCase(
    key
  )}Schema> {
  ${nullable.join('\n')}
}
`;

  fs.mkdir(`./src/validator/${key}`, err => {
    if (err) {
      if (err.errno !== -17 && err.errno !== -4075) {
        return;
      }
    }
    fs.writeFileSync(`./src/validator/${key}/${key}.ts`, tpl, {
      encoding: 'utf-8',
    });
  });
}

function main() {
  const schema = require(`./schema/${folderName}.json`);
  create_entity(schema, folderName);
  create_service(folderName);
  create_controller(folderName);
  create_validator(schema, folderName);
  runYarnCommand('lint:fix');
  console.log('实体初始化完成');
}

main();
